﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UofCASE.AgileProductLinerDSL;
using Microsoft.VisualStudio.Modeling;

namespace APLDTests {
    [TestClass]
    public class TestConnectBuilderTest {

        [TestMethod]
        public void TestConnect() {
            ModelHelper model = ModelHelper.GetModel(true);

            Feature feature4 = model.GetElement<Feature>("feature4");
            Test test2 = model.GetElement<Test>("test2");
            Assert.AreEqual(2, test2.FeaturePorts.Count);

            using (Transaction t = model.Store.TransactionManager.BeginTransaction("add connection between feature 4 and test 2")) {

                TestConnectBuilder.Connect(feature4, test2);
                t.Commit();
            }

            Assert.AreEqual(3, test2.FeaturePorts.Count);
        }

        [TestMethod]
        public void TestConnect2() {
            ModelHelper model = ModelHelper.GetModel(true);

            using (Transaction t = model.Store.TransactionManager.BeginTransaction("delete test connection 4")) {
                model.GetElement<ModelElement>("testConModel4").Delete();
                t.Commit();
            }

            Assert.IsTrue(model.GetElement<ModelElement>("testConModel4").IsDeleted);

            Feature feature4 = model.GetElement<Feature>("feature4");
            Test test3 = model.GetElement<Test>("test3");
            Assert.AreEqual(0, test3.FeaturePorts.Count);
            Assert.IsNull(feature4.TestPort);

            using (Transaction t = model.Store.TransactionManager.BeginTransaction("add connection between feature 4 and test 2")) {

                TestConnectBuilder.Connect(feature4, test3);
                t.Commit();
            }

            Assert.IsNotNull(feature4.TestPort);
            Assert.AreEqual(1, test3.FeaturePorts.Count);
            Assert.IsNotNull(TestPortReferencesFeaturePorts.GetLink(feature4.TestPort, test3.FeaturePorts[0]));
        }

        [TestMethod]
        public void TestCanAcceptSource() {
            ModelHelper model = ModelHelper.GetModel(true);

            Assert.IsTrue(TestConnectBuilder.CanAcceptSource(model.GetElement<ModelElement>("test")));
            Assert.IsTrue(TestConnectBuilder.CanAcceptSource(model.GetElement<ModelElement>("feature")));
            Assert.IsTrue(TestConnectBuilder.CanAcceptSource(model.GetElement<ModelElement>("testPort")));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSource(model.GetElement<ModelElement>("featureModel")));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSource(model.GetElement<ModelElement>("featurePort")));
        }

        [TestMethod]
        public void TestCanAcceptSourceAndTarget() {
            ModelHelper model = ModelHelper.GetModel(true);


            ModelElement feature = model.GetElement<ModelElement>("feature");
            ModelElement feature2 = model.GetElement<ModelElement>("feature2");
            ModelElement test = model.GetElement<ModelElement>("test");
            ModelElement featureModel = model.GetElement<ModelElement>("featureModel");
            ModelElement testPort = model.GetElement<ModelElement>("testPort");
            ModelElement testPort2 = model.GetElement<ModelElement>("testPort2");

            //is allowed
            Assert.IsTrue(TestConnectBuilder.CanAcceptSourceAndTarget(test, feature));
            Assert.IsTrue(TestConnectBuilder.CanAcceptSourceAndTarget(feature, test));
            Assert.IsTrue(TestConnectBuilder.CanAcceptSourceAndTarget(testPort2, test));
            Assert.IsTrue(TestConnectBuilder.CanAcceptSourceAndTarget(test, testPort2));

            //false because a link already exists
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(testPort, test));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(test, testPort));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(test, feature2));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(feature2, test));

            //false because not allowed
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(test, test));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(feature, feature));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(testPort, feature));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(feature, testPort));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(feature, featureModel));
            Assert.IsFalse(TestConnectBuilder.CanAcceptSourceAndTarget(test, featureModel));
        }
    }
}
